#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/1/11 12:08
# @Author : 闫峰
# @File    : execute_strategy.py
import decimal
from decimal import Decimal
import requests
import os
import time
from common.setting import ensure_path_sep
from utils.logging_tool.log_control import LogHandler
from utils.mysqlUtils.db_pool import Database
from utils.mysqlUtils.mongodb_utils import MongoDBLink

current_path = os.path.abspath(__file__)
current_dir = os.path.dirname(current_path)
path_list = current_path.split("\\")
dis_path = "\\".join(path_list[-2:-1])


def remove_file(info_path):
    if os.path.exists(info_path):
        os.remove(info_path)
    else:
        print(f"{info_path} 不存在")


info_path = ensure_path_sep(f"\\logs\\info-{dis_path}{time.time()}")
error_path = ensure_path_sep(f"\\logs\\\error-{dis_path}{time.time()}.log")
warning_path = ensure_path_sep(f"\\logs\\warning-{dis_path}{time.time()}.log")
remove_file(info_path)
remove_file(error_path)
remove_file(warning_path)
INFO = LogHandler(info_path, level='info')
ERROR = LogHandler(error_path, level='error')
WARNING = LogHandler(warning_path, level='warning')


class ExecuteStrategy:
    db = Database(ensure_path_sep("\\config\\shopeev2_config.yaml.bak"), "test_jdw_database")
    # 定义mongodb
    t_sku_strategy_relation_modb = MongoDBLink(
        uri='mongodb://admin:Zhcx?2021@10.158.158.29:27017/?authSource=admin',
        dbname='test_zhcxkj_java_center', coll_name='t_sku_strategy_relation')

    def __init__(self, strategy_id):
        self.strategy_id = strategy_id
        # 查询刊登策略绑定的产品分级策略和listing分级策略
        get_t_strategy_allegro = """
             SELECT b.rule_code,
             b.filter_val
     FROM test_zhcxkj_center_strategy_comprehensive.t_strategy_allegro a
     left join test_zhcxkj_center_strategy_comprehensive.t_strategy_rule_allegro b on a.id = b.strategy_id
    WHERE a.id = %s
    and  a.status= 1
        """

        t_strategy_allegro = self.db.fetch_all_tuple(get_t_strategy_allegro, (strategy_id,))

        self.product_model = None
        self.publish_model = None
        self.listing_model = None
        if not len(t_strategy_allegro):
            raise Exception("策略状态是禁用")
        for i in t_strategy_allegro:
            if i[0] == 'product_model':
                self.product_model = int(i[1])
            elif i[0] == 'publish_model':
                self.publish_model = int(i[1])
            elif i[0] == 'listing_model':
                self.listing_model = int(i[1])
        get_specify_list = f"""
        select import_val from zhcxkj_center_strategy_comprehensive.t_strategy_import_filter_allegro
        where import_id =%s
        """
        specify_list = self.db.fetch_all_tuple(get_specify_list, (strategy_id,))
        if len(specify_list):
            self.specify_list = [i[0] for i in specify_list]
        get_source_id_list = f"""
        select source_id from zhcxkj_center_strategy_comprehensive.t_strategy_source_allegro
        where strategy_id =%s
        """
        self.source_id_list = self.db.fetch_all_tuple(get_source_id_list, (strategy_id,))

    def test_execute_strategy(self):
        for source_id in self.source_id_list:
            source_id = source_id[0]
            self.execute_strategy_by_source_id(source_id)
    def execute_strategy_by_source_id(self, source_id):
        able_category_id_list = self.get_category_id_list(source_id)
        t_allegro_listing_template_detail = f"t_allegro_listing_template_detail_{self.listing_model}"
        t_allegro_listing_template_detail_modb = MongoDBLink(
            uri='mongodb://admin:Zhcx?2021@10.158.158.29:27017/?authSource=admin',
            dbname='test_zhcxkj_java_center', coll_name=t_allegro_listing_template_detail)
        if self.specify_list:
            filter_sql = {
                "$and": [
                    {"sku": {"$in": self.specify_list}},
                    {"strategy_relation.strategy_id": self.product_model}
                ]
            }
            projection1 = {"_id": 1, "sku": 1}
            res_id_index = self.t_sku_strategy_relation_modb.select_skip_projection_limit(filter_sql,
                                                                                          projection1, "_id", 5000)
            sku_set = list(map(lambda x: x['sku'], res_id_index))
            if self.listing_model:
                # 获取最小的ObjectId
                filters_ObjectId_min = {
                    "$and": [
                        {"sourceId": source_id},
                        {"sku": {"$in": sku_set}}
                    ]
                }
                projection1 = {"_id": 1, "sku": 1}
                res_id_index = t_allegro_listing_template_detail_modb.select_skip_projection_limit(filters_ObjectId_min,
                                                                                                   projection1, "_id",
                                                                                                   5000)
                sku_set = set(map(lambda x: x['sku'], res_id_index))
            sku_set = set(sku_set)
        elif not self.listing_model:
            filters_ObjectId_min = {
                "$and": [
                    {"strategy_relation.strategy_id": self.product_model}
                ]
            }
            projection1 = {"_id": 1, "sku": 1}
            res_id_index = self.t_sku_strategy_relation_modb.select_skip_projection_limit(filters_ObjectId_min,
                                                                                          projection1, "_id", 1)
            if not res_id_index:
                return
            first_data = res_id_index
            _id_index = res_id_index[0]['_id']
            sku_set = set()
            while True:
                filters_ObjectId = {
                    "$and": [
                        {"strategy_relation.strategy_id": self.product_model},
                        {"_id": {"$gt": _id_index}}
                    ]
                }
                # filter_sql = {"listingTemplateId": listing_template_id, "sourceId":source_id,"_id": {"$gte": _id_index }}

                field_ = {"_id": 1, "sku": 1}
                actual_sku_list = self.t_sku_strategy_relation_modb.select_skip_projection_limit(filters_ObjectId,
                                                                                                 field_, "_id", 1000)
                if first_data:
                    actual_sku_list.insert(0, first_data[0])
                    first_data.clear()
                if not len(actual_sku_list):
                    break
                _id_index = actual_sku_list[-1].get('_id')
                sku_set |= set(map(lambda x: x['sku'], actual_sku_list))
            print()
        else:
            expect_offer_id_set = set()
            # 获取最小的ObjectId
            filters_ObjectId_min = {
                "$and": [
                    {"listingTemplateId": self.listing_model},
                    {"sourceId": source_id}
                ]
            }
            projection1 = {"_id": 1, "sku": 1}
            res_id_index = t_allegro_listing_template_detail_modb.select_skip_projection_limit(filters_ObjectId_min,
                                                                                               projection1, "_id", 1)
            if not res_id_index:
                return
            first_data = res_id_index
            _id_index = res_id_index[0]['_id']
            sku_set = set()
            while True:
                filters_ObjectId = {
                    "$and": [
                        {"listingTemplateId": self.listing_model},
                        {"sourceId": source_id},
                        {"_id": {"$gt": _id_index}}
                    ]
                }
                field_ = {"sku": 1, "_id": 1}
                actual_sku_list = t_allegro_listing_template_detail_modb.select_skip_projection_limit(filters_ObjectId,
                                                                                                      field_, "_id",
                                                                                                      100)
                if first_data:
                    actual_sku_list.insert(0, first_data[0])
                    first_data.clear()
                if not len(actual_sku_list):
                    break
                _id_index = actual_sku_list[-1].get('_id')
                # TODO
                # 模版结果表中存在sku没有的数据 14979366344
                actual_sku_list = list(filter(lambda x: x.get('sku', None) != None, actual_sku_list))

                sku_list_map = list(map(lambda x: x['sku'], actual_sku_list))

                # 取交集
                filters_ObjectId_exist = {
                    "$and": [
                        {"strategy_relation.strategy_id": self.product_model},
                        {"sku": {"$in": sku_list_map}}
                    ]
                }
                filters_ObjectId_exist_projection = {"sku": 1}
                actual_sku_list_filter = self.t_sku_strategy_relation_modb.select(filters_ObjectId_exist,
                                                                                  filters_ObjectId_exist_projection)
                actual_sku_set_map = set(map(lambda x: x['sku'], actual_sku_list_filter))
                sku_set |= actual_sku_set_map
            print()

        # 得到一个sku_set  类目权限过滤
        sku_set_filter = self.category_filter(sku_set, source_id, able_category_id_list)
        # 得到一个actual_offer_id_set
        self.check_sku(self.strategy_id, sku_set_filter)

    def check_sku(self, strategy_id, sku_set):
        check_sql = f"""
        SELECT b.sku FROM test_zhcxkj_center_strategy_comprehensive.t_strategy_queue_allegro a
        LEFT JOIN test_zhcxkj_center_strategy_comprehensive.t_publish_detail_allegro b on a.id=b.queue_id
        WHERE a.strategy_id= %s
        """
        actual_sku_list = self.db.fetch_all_tuple(check_sql, (strategy_id,))
        if not len(actual_sku_list):
            actual_sku_set = set()
        actual_sku_set = set(map(lambda x: x[0], actual_sku_list))
        if sku_set != actual_sku_set:
            lack = sku_set - actual_sku_set
            more = actual_sku_set - sku_set
            print()

    def category_filter(self, sku_set, source_id, able_category_id_list):

        get_sku_category = f"""
        SELECT sku,other_node_id FROM test_zhcxkj_center_category.t_sku_category WHERE platform_type=67 and 	sku in %s
        """
        sku_category = self.db.fetch_all_tuple(get_sku_category, (sku_set,))
        sku_category = tuple(map(lambda x: (x[0], int(x[1])), sku_category))
        filter_sku_set = set(filter(lambda x: x[1] in able_category_id_list, sku_category))
        filter_sku_set = set(map(lambda x: x[0], filter_sku_set))
        return filter_sku_set

    def get_category_id_list(self, source_id):
        get_category_id_list = f"""
        select t.category_id from test_zhcxkj_center_strategy_comprehensive.t_allegro_publish_source_category t 
        where t.source_id = %s
        """
        category_id_list = self.db.fetch_all_tuple(get_category_id_list, (source_id,))
        if not len(category_id_list):
            return []
        return list(map(lambda x: x[0], category_id_list))


if __name__ == '__main__':

    ExecuteStrategy(15).test_execute_strategy()
    # ExecuteStrategy(1,9058).check_actual_offer_id_set()
